package cn.shop.merchant.config;

import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.shop.merchant.model.logs.MerchantLog;
import cn.shop.merchant.model.user.UserInfoForSession;
import cn.shop.utils.annotation.OperationLog;
import cn.shop.utils.constant.Constant;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import static cn.shop.utils.constant.Constant.UID;

/**
 * 全局日志
 *
 * @author 痴
 * @className LogRecordAspect
 * @since 2020-07-15 09:19
 */
@Aspect
@Component
@Slf4j
public class LogRecordAspect {

	@Resource
	private LogAsync logAsync;

	@AfterReturning(value = "@annotation(operationLog)", returning = "keys", argNames = "joinPoint,keys,operationLog")
	public void doAround(JoinPoint joinPoint, Object keys, OperationLog operationLog) {
		MerchantLog backLog = new MerchantLog();
		SaSession session = StpUtil.getSession(false);
		if (session != null) {
			UserInfoForSession currentUser = (UserInfoForSession) session.get(Constant.USER);
			backLog.setCreateId(currentUser.getId());
			backLog.setAccount(currentUser.getAccount());
			backLog.setName(currentUser.getName());
			backLog.setUid(session.getLong(UID));
		}
		backLog.setDetails(StrUtil.format("{} , 详细参数 : {}", operationLog.desc(), getRequestParams(joinPoint)));
		backLog.setType(operationLog.type());
		backLog.setRetValue(JSONUtil.toJsonStr(keys));
		logAsync.operationLog(backLog);
	}

	/**
	 * 封装 日志信息
	 *
	 * @param joinPoint 切入点
	 */
	private String getRequestParams(JoinPoint joinPoint) {
		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes sra = (ServletRequestAttributes) ra;
		assert sra != null;
		HttpServletRequest request = sra.getRequest();
		String httpMethod = request.getMethod();
		String queryString = request.getQueryString();
		Object[] args = joinPoint.getArgs();
		String params = "";
		if (args.length > 0) {
			if ("GET".equals(httpMethod) || "DELETE".equals(httpMethod)) {
				params = queryString;
			}
			else {
				for (int i = 0; i < args.length; i++) {
					if (args[i] instanceof ServletRequest) {
						args[i] = ((HttpServletRequest) args[i]).getParameterMap();
					}
					else if (args[i] instanceof ServletResponse) {
						args[i] = "response对象";
					}
					else if (args[i] instanceof MultipartFile) {
						args[i] = "MultipartFile对象";
					}
					else if (args[i] instanceof MultipartFile[]) {
						args[i] = "MultipartFile数组对象";
					}
					else if (args[i] instanceof BindingResult) {
						args[i] = "BindingResult对象";
					}
				}
				params = JSONUtil.toJsonStr(args);
			}
		}
		return params;

	}

}
